/*
 * ModelCC, distributed under ModelCC Shared Software License, www.modelcc.org
 */

package org.modelcc.language.syntax.builder;

import org.modelcc.language.factory.ListContent;
import org.modelcc.language.syntax.ParserMetadata;
import org.modelcc.language.syntax.RuleSymbol;
import org.modelcc.language.syntax.Symbol;
import org.modelcc.language.syntax.SymbolBuilder;
import org.modelcc.lexer.recognizer.PatternRecognizer;

/**
 * List symbol builder (L ::= L L) 
 * 
 * @author Fernando Berzal (berzal@acm.org)
 */
public class ListListSymbolBuilder extends SymbolBuilder
{
	private int list1;
	private int list2;

	/**
	 * Constructor
	 * @param list1 First list index within rule RHS
	 * @param list2 Second list index within rule RHS
	 */
	public ListListSymbolBuilder(int list1, int list2)
	{
		this.list1 = list1;
		this.list2 = list2;
	}

	@Override
	public boolean build(Symbol t, ParserMetadata data) 
	{
        ListContent l0 = (ListContent)t.getContent(list1).getUserData();
        ListContent l1 = (ListContent)t.getContent(list2).getUserData();
        if (l0 == null)
        	l0 = new ListContent(new Object[0]);
        if (l1 == null)
        	l1 = new ListContent(new Object[0]);
        
        Object[] l = new Object[l0.getContent().length+l1.getContent().length];
        Object[] rest = l0.getContent();
        for (int i = 0;i < rest.length;i++)
            l[i] = rest[i];
        rest = l1.getContent();
        for (int i = 0;i < rest.length;i++)
            l[i+l0.getContent().length] = rest[i];
        
        Symbol extra = null;
        RuleSymbol extraRuleElement = null;
        for (int i=0; i<t.size();i++) {
        	if ((i!=list1) && (i!=list2) && !PatternRecognizer.class.isAssignableFrom(t.getContent(i).getType().getClass())) {
        		extra = t.getContent(i);
        		extraRuleElement = t.getElement(i);
        	}
        }

        t.setUserData(new ListContent(l,extra,extraRuleElement));
        return true;
	}
}
